import bpy
import bpy.props
import bmesh

bl_info = {
    "name" : "Vertex Custom Smooth",
    "author": "FuZhiBo",
    "version": (0,0,1),
    "blender": (2, 61, 0),
    "location": "Object > Vertex Align Smooth",
    "description": "Custom Smooth verties",
    "warning": "", # used for warning icon and text in addons panel
    "wiki_url": "http://git.oschina.net/mobilefzb/blender_plug_mode_factory",
    "category": "Vertex Custom Smooth"
}

#define a operator
class BmeshOpsSmoothVertOperator(bpy.types.Operator):
    """use bmesh.ops.smooth_vert"""
    bl_idname = "object.bmesh_ops_smooth_vert_test";
    bl_label = "Smooths vertices by using a basic vertex averaging scheme";
    @classmethod
    def poll(self,context):
        if context.active_object is not None:
            obj = context.active_object;
            if obj.mode == 'EDIT':
                return True;
            else :
                return False;
        else :
            return False;
    def execute(self,context):
        #vert_list = [];
        obj = context.object;
        bm = bmesh.from_edit_mesh(obj.data);
        #for v in bm.verts:
        #    if v.select:
        #        vert_list.append(v);
        #can only pass bm argument in,others will cause error
        #TypeError: bmesh operators expect a single BMesh positional
        # argument, all other args must be keywords
        #no return value
        bmesh.ops.smooth_vert(bm);#after to call this nothing happen...
        return {"FINISHED"};
        
class BmeshOpsSmoothLaplacianVertOperator(bpy.types.Operator):
    """use bmesh.ops.smooth_laplacian_vert"""
    bl_idname = "object.bmesh_ops_smooth_laplacian_vert_test";
    bl_label = "Vertext Smooth Laplacian.";
    @classmethod
    def poll(self,context):
        if context.active_object is not None:
            obj = context.active_object;
            if obj.mode == 'EDIT':
                return True;
            else :
                return False;
        else :
            return False;
    def execute(self,context):
        #vert_list = [];
        obj = context.object;
        bm = bmesh.from_edit_mesh(obj.data);
        #for v in bm.verts:
        #    if v.select:
        #        vert_list.append(v);
        #TypeError: bmesh operators expect a single BMesh positional
        # argument, all other args must be keywords
        #no return value
        bmesh.ops.smooth_laplacian_vert(bm);#after to call this nothing happen...
        return {"FINISHED"};
        
class BpyOpsMeshVerticesSmoothOperator(bpy.types.Operator):
    """use bpy.ops.mesh.vertices_smooth"""
    bl_idname = "object.bpy_ops_mesh_vertices_smooth_test";
    bl_label = "Flatten angles of selected vertices.";
    @classmethod
    def poll(self,context):
        if context.active_object is not None:
            obj = context.active_object;
            if obj.mode == 'EDIT' :
                return True;
            else :
                return False;
        else :
            return False;
    def execute(self,context):
        obj = context.active_object;
        bpy.ops.mesh.vertices_smooth(repeat=obj.nav_smooth_repeate_times,
                                            xaxis=obj.nav_smooth_xaxis,
                                            yaxis=obj.nav_smooth_yaxis,
                                            zaxis=obj.nav_smooth_zaxis);
        return {"FINISHED"};
        
class BpyOpsMeshVerticesSmoothLaplacianOperator(bpy.types.Operator):
    """use bpy.ops.mesh.vertices_smooth_laplacian"""
    bl_idname = "object.bpy_ops_mesh_vertices_smooth_laplacian_test";
    bl_label = "Laplacian smooth of selected vertices";
    @classmethod
    def poll(self,context):
        if context.active_object is not None:
            obj = context.active_object;
            if obj.mode == 'EDIT' :
                return True;
            else :
                return False;
        else :
            return False;
    def execute(self,context):
        bpy.ops.mesh.vertices_smooth_laplacian(lambda_factor=0, lambda_border=0);
        return {"FINISHED"};
class VertiesCustomSmoothPanel(bpy.types.Panel):
    """build a panel and run my operator"""
    bl_idname = "panel_verties_custom_smooth";
    bl_label = "Verties Custom Smooth Panel";
    bl_space_type = "PROPERTIES";
    bl_region_type = "WINDOW";
    bl_context = "object";
    def draw(self,context):
        ui_layout = self.layout;
        ###
        ui_row = ui_layout.row();
        ui_row.label(text="\"bmesh.ops\" smooth api",icon = "UV_VERTEXSEL");
        ###
        ui_row = ui_layout.row();
        ui_row.operator("object.bmesh_ops_smooth_vert_test","smooth_vert");
        ###
        ui_row = ui_layout.row();
        ui_row.operator("object.bmesh_ops_smooth_laplacian_vert_test",
                                    "smooth_laplacian_vert");
        ###
        ui_row = ui_layout.row();
        ui_row.label(text="\"bpy.ops.mesh\" smooth api",icon = "UV_VERTEXSEL");
        ###
        ui_box = ui_layout.box();
        obj = context.active_object;
        ####
        ui_row = ui_box.row();
        ui_row.prop(obj,"nav_smooth_repeate_times");
        ####
        ui_row = ui_box.row();
        ui_column = ui_row.column();
        ui_column.prop(obj,"nav_smooth_xaxis");
        ui_column = ui_row.column();
        ui_column.prop(obj,"nav_smooth_yaxis");
        ui_column = ui_row.column();
        ui_column.prop(obj,"nav_smooth_zaxis");
        ####
        ui_row = ui_box.row();
        ui_row.operator("object.bpy_ops_mesh_vertices_smooth_test","vertices_smooth");
        ####
        ui_row = ui_box.row();
        ui_row.operator(operator="object.bpy_ops_mesh_vertices_smooth_laplacian_test",
                                                text="vertices_smooth_laplacian");
        ####
        
def register():
    bpy.types.Object.nav_smooth_repeate_times = bpy.props.IntProperty(name="repeate times",
                                            description="smooth times in one operator",default=1);
    bpy.types.Object.nav_smooth_xaxis = bpy.props.BoolProperty(name="x",
                                            description="allow smooth x directory");
    bpy.types.Object.nav_smooth_yaxis = bpy.props.BoolProperty(name="y",
                                            description="allow smooth y directory");
    bpy.types.Object.nav_smooth_zaxis = bpy.props.BoolProperty(name="z",
                                            description="allow smooth z directory");
    bpy.utils.register_class(BmeshOpsSmoothVertOperator);
    bpy.utils.register_class(BmeshOpsSmoothLaplacianVertOperator);
    bpy.utils.register_class(BpyOpsMeshVerticesSmoothOperator);
    bpy.utils.register_class(BpyOpsMeshVerticesSmoothLaplacianOperator);
    bpy.utils.register_class(VertiesCustomSmoothPanel);
    
def unregister():
    del bpy.types.Object.nav_smooth_repeate_times;
    del bpy.types.Object.nav_smooth_xaxis;
    del bpy.types.Object.nav_smooth_yaxis;
    del bpy.types.Object.nav_smooth_zaxis;
    bpy.utils.unregister_class(BmeshOpsSmoothVertOperator);
    bpy.utils.unregister_class(BmeshOpsSmoothLaplacianVertOperator);
    bpy.utils.unregister_class(BpyOpsMeshVerticesSmoothOperator);
    bpy.utils.unregister_class(BpyOpsMeshVerticesSmoothLaplacianOperator);
    bpy.utils.unregister_class(VertiesCustomSmoothPanel);
    
if __name__ == "__main__":
    register();
